﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Configuration;
using System.Windows.Forms;

namespace DotNETX.Version.Manager
{
    public class ManagerViewModel : BaseViewModel
    {
        #region CONST
        public const string CONFIGKEY_SERVER_VIRTUALDIRECTORY = "DotNETX.Version.Manager.ServerVirtualDirectory";
        public const string CONFIGKEY_VERSIONINI_LOCATION = "DotNETX.Version.Manager.VersionIniRefLocation";
        public const string CONFIGKEY_TEMP_DIRECTORY = "DotNETX.Version.Manager.TempDirectory";

        public const string CONFIGKEY_VERSIONSERVICE_IP = "DotNETX.Version.Manager.VersionServiceIp";
        public const string CONFIGKEY_VERSIONSERVICE_PORT = "DotNETX.Version.Manager.VersionServicePort";
        public const string CONFIGKEY_VERSIONSERVICE_PROTOCAL = "DotNETX.Version.Manager.VersionServiceProtocal";

        public const string CONFIGKEY_FILESERVICE_IP = "DotNETX.Version.Manager.FileServiceIp";
        public const string CONFIGKEY_FILESERVICE_PORT = "DotNETX.Version.Manager.FileServicePort";
        public const string CONFIGKEY_FILESERVICE_PROTOCAL = "DotNETX.Version.Manager.FileServiceProtocal";
        #endregion

        public ManagerViewModel()
        {
            if (App.IsInDesignMode) return;

            ReadConfig();
            Initial();
        }

        private void Initial()
        {
            try
            {
                BackgroundWorker bw = new BackgroundWorker();
                bw.DoWork += (s, e) =>
                {
                    VersionClient = VersionClient.Create(VersionServiceIp, VersionServicePort, VersionServiceProtocal);
                    FilemgrClient = FileServer.FileManagerClient.Create(FileServiceIp, FileServicePort, FileServiceProtocal);
                    UpgradeClient = new UpgradeClient(VirtualDir, VersionClient, FilemgrClient);
                    UpgradeClient.CompressPackageStart += () => { Msg = "打包："; };
                    UpgradeClient.CompressPackageProgress += (p) => { Progress = p * 100; };
                    UpgradeClient.CompressPackageComplete += (b) => { if (b) Msg = "打包完成："; else Msg = "打包失败："; };
                    UpgradeClient.UploadPackageStart += () => { Msg = "上传："; Progress = 0; };
                    UpgradeClient.UploadPackageProgress += (p) => { Progress = p * 100; };
                    UpgradeClient.UploadPackageComplete += (b) =>
                    {
                        IsBusy = false;
                        if (b)
                        {
                            Msg = "上传成功：";
                            CurrentVersion = VersionClient.GetLatestVersion().VersionName;
                        }
                        else Msg = "上传失败:";
                    };


                    Version.VersionInfo vi = VersionClient.GetLatestVersion();
                    CurrentVersion = vi.VersionName;
                };
                bw.RunWorkerCompleted += (s, e) =>
                {
                    IsBusy = false;
                };
                bw.RunWorkerAsync();
                IsBusy = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "异常");
            }
        }

        private void ReadConfig()
        {
            Type type = this.GetType();
            VirtualDir = TryGetAppSetting(type, CONFIGKEY_SERVER_VIRTUALDIRECTORY);
            VersionIniLocation = TryGetAppSetting(type, CONFIGKEY_VERSIONINI_LOCATION);
            TempDir = TryGetAppSetting(type, CONFIGKEY_TEMP_DIRECTORY);

            VersionServiceIp = TryGetAppSetting(type, CONFIGKEY_VERSIONSERVICE_IP);
            VersionServicePort = int.Parse(TryGetAppSetting(type, CONFIGKEY_VERSIONSERVICE_PORT));
            VersionServiceProtocal = TryGetAppSetting(type, CONFIGKEY_VERSIONSERVICE_PROTOCAL);

            FileServiceIp = TryGetAppSetting(type, CONFIGKEY_FILESERVICE_IP);
            FileServicePort = int.Parse(TryGetAppSetting(type, CONFIGKEY_FILESERVICE_PORT));
            FileServiceProtocal = TryGetAppSetting(type, CONFIGKEY_FILESERVICE_PROTOCAL);
        }

        #region Property

        UpgradeClient UpgradeClient = null;
        VersionClient VersionClient = null;
        FileServer.FileManagerClient FilemgrClient = null;

        public string VirtualDir { get; private set; }
        public string VersionIniLocation { get; private set; }
        public string TempDir { get; private set; }
        #endregion

        #region NP

        protected bool _IsBusy;
        public bool IsBusy
        {
            get { return _IsBusy; }
            set
            {
                _IsBusy = value;
                NotifyPropertyChanged("IsBusy");
                DoUpgradeCommand.RaiseCanExecuteChanged();
            }
        }

        private string _versionServiceIp = null;
        public string VersionServiceIp
        {
            get { return _versionServiceIp; }
            set
            {
                _versionServiceIp = value;
                NotifyPropertyChanged("VersionServiceIp");
            }
        }

        protected int _versionServicePort;
        public int VersionServicePort
        {
            get { return _versionServicePort; }
            set
            {
                _versionServicePort = value;
                NotifyPropertyChanged("VersionServicePort");
            }
        }

        protected string _versionServiceProtocal;
        public string VersionServiceProtocal
        {
            get { return _versionServiceProtocal; }
            set
            {
                _versionServiceProtocal = value;
                NotifyPropertyChanged("VersionServiceProtocal");
            }
        }

        protected int _fileServicePort;
        public int FileServicePort
        {
            get { return _fileServicePort; }
            set
            {
                _fileServicePort = value;
                NotifyPropertyChanged("FileServicePort");
            }
        }

        protected string _fileServiceProtocal;
        public string FileServiceProtocal
        {
            get { return _fileServiceProtocal; }
            set
            {
                _fileServiceProtocal = value;
                NotifyPropertyChanged("FileServiceProtocal");
            }
        }

        private string _fileServiceIp = null;
        public string FileServiceIp
        {
            get { return _fileServiceIp; }
            set
            {
                _fileServiceIp = value;
                NotifyPropertyChanged("FileServiceIp");
            }
        }

        private string _currentVersion = null;
        public string CurrentVersion
        {
            get { return _currentVersion; }
            set
            {
                _currentVersion = value;
                NotifyPropertyChanged("CurrentVersion");
            }
        }

        private string _newVersion = null;
        public string NewVersion
        {
            get { return _newVersion; }
            set
            {
                _newVersion = value;
                NotifyPropertyChanged("NewVersion");
            }
        }

        private string _description = null;
        public string Description
        {
            get { return _description; }
            set
            {
                _description = value;
                NotifyPropertyChanged("Description");
            }
        }

        private string _upgradeFilesDirectory = null;
        public string UpgradeFilesDirectory
        {
            get { return _upgradeFilesDirectory; }
            set
            {
                _upgradeFilesDirectory = value;
                NotifyPropertyChanged("UpgradeFilesDirectory");
                if (null != value && System.IO.File.Exists(System.IO.Path.Combine(value, VersionIniLocation)))
                {
                    Version.VersionInfo vi = Version.IniVersionInfo.VersionInfoUtils.ReadVersionInfo(System.IO.Path.Combine(value, VersionIniLocation));
                    NewVersion = vi.VersionName;
                    Description = vi.Description;
                }
            }
        }


        protected string _Msg;
        public string Msg
        {
            get { return _Msg; }
            set
            {
                _Msg = value;
                NotifyPropertyChanged("Msg");
            }
        }

        protected double _Progress;
        public double Progress
        {
            get { return _Progress; }
            set
            {
                _Progress = value;
                NotifyPropertyChanged("Progress");
            }
        }

        #endregion

        #region Commands

        private DelegateCommand _openUpgradeDirectoryCommand = null;
        public DelegateCommand OpenUpgradDirectoryCommand
        {
            get
            {
                if (null == _openUpgradeDirectoryCommand)
                {
                    _openUpgradeDirectoryCommand = new DelegateCommand(OpenUpgradDirectory);
                }
                return _openUpgradeDirectoryCommand;
            }
        }

        public void OpenUpgradDirectory()
        {
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            if (!string.IsNullOrEmpty(UpgradeFilesDirectory)) folderBrowserDialog.SelectedPath = UpgradeFilesDirectory;

            if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
            {
                this.UpgradeFilesDirectory = folderBrowserDialog.SelectedPath;
            }
        }

        private DelegateCommand _DoUpgradeCommand = null;
        public DelegateCommand DoUpgradeCommand
        {
            get
            {
                if (_DoUpgradeCommand == null)
                {
                    _DoUpgradeCommand = new DelegateCommand(DoUpgrade, () => { return !IsBusy; });
                } return _DoUpgradeCommand;
            }
            set { _DoUpgradeCommand = value; NotifyPropertyChanged("DoUpgradeCommand"); }
        }

        public void DoUpgrade()
        {
            bool updateFlag = false;
            Version.VersionInfo versionInfo = new VersionInfo() { VersionName = NewVersion, Description = Description, ReleaseDate = DateTime.Now };
            if( null == NewVersion)
            {
                MessageBox.Show("未设置新版本号！", "提示");
                return;
            }
            if ( NewVersion == CurrentVersion)
            {
                MessageBox.Show("新版本号与当前版本号重复！", "提示");
                return;
            }
            if (System.IO.File.Exists(System.IO.Path.Combine(UpgradeFilesDirectory, VersionIniLocation)))
            {
                Version.VersionInfo vi = Version.IniVersionInfo.VersionInfoUtils.ReadVersionInfo(System.IO.Path.Combine(UpgradeFilesDirectory, VersionIniLocation));
                if (vi.VersionName != versionInfo.VersionName || vi.Description != versionInfo.Description)
                {
                    updateFlag = true;
                }
            }
            else
            {
                updateFlag = true;
            }
            if (updateFlag) Version.IniVersionInfo.VersionInfoUtils.WriteVersionInfo(System.IO.Path.Combine(UpgradeFilesDirectory, VersionIniLocation), versionInfo);
            UpgradeClient.UploadPakage(UpgradeFilesDirectory, versionInfo);
            IsBusy = true;
        }
        #endregion

        private static string TryGetAppSetting(Type type, string key)
        {
            Configuration config = ConfigurationManager.OpenExeConfiguration(type.Assembly.Location);
            if (config.AppSettings.Settings.AllKeys.Contains(key))
            {
                return config.AppSettings.Settings[key].Value;
            }
            else
            {
                return ConfigurationManager.AppSettings[key];
            }
        }
    }
}
